﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace l1cs.server.serverpackets
{
    public abstract class ServerBasePacket
    {
        private static Logger _log = Logger.getLogger( typeof( ServerBasePacket ).FullName );

        private readonly String CLIENT_LANGUAGE_CODE = Config.CLIENT_LANGUAGE_CODE;

        protected List<byte> _bao = new List<byte>();

        protected ServerBasePacket() { }

        protected void writeD( int value )
        {
            _bao.Add( (byte)( value & 0xff ) );
            _bao.Add( (byte)( value >> 8 & 0xff ) );
            _bao.Add( (byte)( value >> 16 & 0xff ) );
            _bao.Add( (byte)( value >> 24 & 0xff ) );
        }

        protected void writeH( int value )
        {
            _bao.Add( (byte)( value & 0xff ) );
            _bao.Add( (byte)( value >> 8 & 0xff ) );
        }

        protected void writeC( int value )
        {
            _bao.Add( (byte)( value & 0xff ) );
        }

        protected void writeP( int value )
        {
            _bao.Add( (byte)( value ) );
        }

        protected void writeL( long value )
        {
            _bao.Add( (byte)( value & 0xff ) );
        }

        //protected void writeF(double org) {
        //    long value = Double.doubleToRawLongBits(org);
        //    _bao.write((int) (value & 0xff));
        //    _bao.write((int) (value >> 8 & 0xff));
        //    _bao.write((int) (value >> 16 & 0xff));
        //    _bao.write((int) (value >> 24 & 0xff));
        //    _bao.write((int) (value >> 32 & 0xff));
        //    _bao.write((int) (value >> 40 & 0xff));
        //    _bao.write((int) (value >> 48 & 0xff));
        //    _bao.write((int) (value >> 56 & 0xff));
        //}

        protected void writeS( String text )
        {
            if ( text != null )
            {
                foreach ( byte data in Encoding.GetEncoding( CLIENT_LANGUAGE_CODE ).GetBytes( text ) )
                {
                    _bao.Add( data );
                }
            }

            _bao.Add( 0 );
        }

        protected void writeByte( byte[] text )
        {
            if ( text != null )
            {
                foreach ( byte data in text )
                {
                    _bao.Add( data );
                }
            }
        }

        public int getLength()
        {
            return _bao.Count + 2;
        }

        public byte[] getBytes()
        {
            int padding = _bao.Count % 4;

            if ( padding != 0 )
            {
                for ( int i = padding; i < 4; i++ )
                {
                    writeC( 0x00 );
                }
            }

            return _bao.ToArray();
        }

        public abstract byte[] getContent();

        /// <summary>
        /// サーバーパケットの種類を表す文字列を返す。("[S] S_WhoAmount" 等)
        /// </summary>
        /// <returns></returns>
        virtual public String getType()
        {
            return "[S] " + this.GetType().Name;
        }
    }
}
